/**
 * 
 */
package cn.nawang.ebeim.client.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * @ClassName: ZipUtil
 * @Description: 对文件或文件夹进行压缩和解压
 * @author 张建峰
 * @date 2015年8月17日 下午5:07:10
 * @version v1.0
 */
public class ZipUtil {
  /** 得到当前系统的分隔符 */
  // private static String separator = System.getProperty("file.separator");

  /**
   * @author 张建峰
   * @Description: 添加到压缩文件中
   * @param @param out
   * @param @param f
   * @param @param base
   * @param @throws Exception
   * @return void
   * @date 2015年8月17日下午5:07:41
   *
   * @修改人 张建峰
   * @修改日期
   */
  private void directoryZip(ZipOutputStream out, File f, String base) throws Exception {
    // 如果传入的是目录
    if (f.isDirectory()) {
      File[] fl = f.listFiles();
      // 创建压缩的子目录
      out.putNextEntry(new ZipEntry(base + "/"));
      if (base.length() == 0) {
        base = "";
      } else {
        base = base + "/";
      }
      for (int i = 0; i < fl.length; i++) {
        directoryZip(out, fl[i], base + fl[i].getName());
      }
    } else {
      // 把压缩文件加入rar中
      out.putNextEntry(new ZipEntry(base));
      FileInputStream in = new FileInputStream(f);
      byte[] bb = new byte[10240];
      int aa = 0;
      while ((aa = in.read(bb)) != -1) {
        out.write(bb, 0, aa);
      }
      in.close();
    }
  }

  /**
   * @author 张建峰
   * @Description: 压缩文件
   * @param @param zos
   * @param @param file
   * @param @throws Exception
   * @return void
   * @date 2015年8月17日下午5:08:00
   *
   * @修改人 张建峰
   * @修改日期
   */
  private void fileZip(ZipOutputStream zos, File file) throws Exception {
    if (file.isFile()) {
      zos.putNextEntry(new ZipEntry(file.getName()));
      FileInputStream fis = new FileInputStream(file);
      byte[] bb = new byte[10240];
      int aa = 0;
      while ((aa = fis.read(bb)) != -1) {
        zos.write(bb, 0, aa);
      }
      fis.close();
      System.out.println(file.getName());
    } else {
      directoryZip(zos, file, "");
    }
  }

  /**
   * @author 张建峰
   * @Description: 解压缩文件
   * @param @param zis
   * @param @param file
   * @param @throws Exception
   * @return void
   * @date 2015年8月17日下午5:08:11
   *
   * @修改人 张建峰
   * @修改日期
   */
  private void fileUnZip(ZipInputStream zis, File file) throws Exception {
    ZipEntry zip = zis.getNextEntry();
    if (zip == null) return;
    String name = zip.getName();
    File f = new File(file.getAbsolutePath() + "/" + name);
    if (zip.isDirectory()) {
      f.mkdirs();
      fileUnZip(zis, file);
    } else {
      f.createNewFile();
      FileOutputStream fos = new FileOutputStream(f);
      byte b[] = new byte[10240];
      int aa = 0;
      while ((aa = zis.read(b)) != -1) {
        fos.write(b, 0, aa);
      }
      fos.close();
      fileUnZip(zis, file);
    }
  }

  /**
   * @author 张建峰
   * @Description: 根据filePath创建相应的目录
   * @param @param filePath
   * @param @return
   * @param @throws IOException
   * @return File
   * @date 2015年8月17日下午5:08:21
   *
   * @修改人 张建峰
   * @修改日期
   */
  private File mkdirFiles(String filePath) throws IOException {
    File file = new File(filePath);
    if (!file.getParentFile().exists()) {
      file.getParentFile().mkdirs();
    }
    file.createNewFile();

    return file;
  }

  /**
   * @author 张建峰
   * @Description: 压缩后的文件位置
   * @param @param path
   * @param @return
   * @return String
   * @date 2015年8月17日下午5:50:55
   *
   * @修改人 张建峰
   * @修改日期
   */
  public String destinationPath(String path) {

    File file = new File(path);
    if (!file.isDirectory()) {
      String filename = file.getName();
      String ab_path = file.getAbsolutePath();
      int idx = ab_path.lastIndexOf(filename);
      path = ab_path.substring(0, idx);
    } else {
      path = file.getParentFile().getAbsolutePath();
    }
    System.out.println(path);
    return path;
  }

  public static void main(String[] args) {

//    new ZipUtil().doZip("E:\\test\\encryptDescrypt\\container\\zjf1.jpg",
//        null);
    
    new ZipUtil().unZip("E:\\test\\encryptDescrypt\\container\\361d2b70-c9b7-4bcd-938c-420f193b413e.zip",
      "E:\\test\\encryptDescrypt\\container\\xxx");
  }

  /**
   * @author 张建峰
   * @Description: 对zipBeforeFile目录下的文件压缩，保存为指定的文件zipAfterFile
   * @param @param zipBeforeFile 压缩之前的文件
   * @return void
   * @date 2015年8月17日下午5:08:33
   *
   * @修改人 张建峰
   * @修改日期
   */
  public void doZip(String zipBeforeFile, String zipLocation) {

    // 如果用户没有自定义压缩后的文件位置，默认在源文件目录中
    if (zipLocation == null || zipLocation.length() == 0) {
      zipLocation = destinationPath(zipBeforeFile);
    }
    // 压缩后的文件
    File desFile = new File(zipLocation + File.separator + UUID.randomUUID().toString() + ".zip");
    String zipAfterFile = desFile.getAbsolutePath();
    try {
      ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(mkdirFiles(zipAfterFile)));
      fileZip(zos, new File(zipBeforeFile));
      zos.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * @author 张建峰
   * @Description: 解压缩文件unZipBeforeFile保存在unZipAfterFile目录下
   * @param @param unZipBeforeFile 解压之前的文件
   * @param @param unZipAfterFile 解压之后的文件
   * @return void
   * @date 2015年8月17日下午5:08:50
   *
   * @修改人 张建峰
   * @修改日期
   */
  public void unZip(String unZipFile, String unZipLocation) {

    // 如果用户没有自定义压缩后的文件位置，默认在源文件目录中
    if (unZipLocation == null || unZipLocation.length() == 0) {
      unZipLocation = destinationPath(unZipFile);
    }
    // 解压后文件
    File desFile = new File(unZipFile);
    String desFilePath = desFile.getAbsolutePath();
    try {
      ZipInputStream zis = new ZipInputStream(new FileInputStream(desFilePath));
      File f = new File(unZipLocation);
      f.mkdirs();
      fileUnZip(zis, f);
      zis.close();
    } catch (Exception e) {
      e.printStackTrace();
    }

  }


  public void unzip(String src, String dst) {
    try {
      ZipInputStream zis = new ZipInputStream(new FileInputStream(src));
      File f = new File(dst);
      f.mkdirs();
      fileUnZip(zis, f);
      zis.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void zip(String src, String dst) {
    try {
      ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(mkdirFiles(dst)));
      fileZip(zos, new File(src));
      zos.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
